#!usr/lib/python
# -*- coding:utf-8 -*-
"""
"""
from struct import pack,unpack
import binascii
import zlib

class ByteArray:
    """ """
    ENDIAN_LETTLE           =   1
    ENDIAN_BIG              =   0

    def __init__(self,buf=None):
        """ """
        self.__buf = ""
        if isinstance(buf,str):
            self.__buf = buf
        elif isinstance(buf,ByteArray):
            self.__buf = buf.getvalue()
        else:
            pass
        self.endian = ByteArray.ENDIAN_BIG;
        self.position = 0;

    def readShort(self):
        """ """
        fmt =   "%sh"%self._isEndian()
        res = unpack(fmt,self._readbuf(2))
        return res[0]
    def readUnsignedShort(self):
        """ """
        fmt =   "%sH"%self._isEndian()
        res = unpack(fmt,self._readbuf(2))
        return res[0]

    def readInt(self):
        """ """
        fmt =   "%si"%self._isEndian()
        res =   unpack(fmt,self._readbuf(4))
        return res[0]
    def readUnsignedInt(self):
        """ """
        fmt =   "%sI"%self._isEndian()
        res =   unpack(fmt,self._readbuf(4))
        return res[0]

    def readFloat(self):
        """ """
        fmt =   "%sf"%self._isEndian()
        res =   unpack(fmt,self._readbuf(4))
        return res[0]

    def readDouble(self):
        """ """
        fmt =   "%sd"%self._isEndian()
        res =   unpack(fmt,self._readbuf(8))
        return res[0]

    def readUTFBytes(self,nlen):
        """ """
        fmt =   "%ss"%(nlen)
        res =   unpack(fmt,self._readbuf(nlen))
        return res[0]

    def readByte(self):
        """ """
        fmt =   "%sb"%self._isEndian()
        res =   unpack(fmt,self._readbuf(1))
        return res[0]

    def readUnsignedByte(self):
        """ """
        fmt =   "%sB"%self._isEndian()
        res =   unpack(fmt,self._readbuf(1))
        return res[0]

    def readMultiByte(self,lenght=-1):
        """ """
        nlen = lenght;
        if nlen == -1:
            cpos = self.position;
            nlen = self.length() - cpos;
        return self._readbuf(nlen)

    def readBytes(self,b,offset=0,nlen=0):
        b.position = offset
        if nlen==0:
            nlen = self.length()-self.position;
        b.writeMuliteBytes(self._readbuf(nlen))
        return b

    def compress(self):
        """zlib压缩"""
        buf = self.getvalue();
        self.__buf = zlib.compress(buf)

    def uncompress(self):
        """zlib解压"""
        buf = self.getvalue();
        self.__buf = zlib.decompress(buf)

    def writeShort(self,value):
        """ """
        assert(type(value) == int)
        fmt =   "%sh"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeUnsignedShort(self,value):
        """ """
        assert(type(value) == int)
        fmt =   "%sH"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeInt(self,value):
        """ """
        assert(type(value) == int)
        fmt =   "%si"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeUnsignedInt(self,value):
        """ """
        assert(type(value) == int)
        fmt =   "%sI"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeFloat(self,value):
        assert(type(value) == float)
        fmt =   "%sf"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeDouble(self,value):
        """ """
        fmt =   "%sd"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeUTFBytes(self,value):
        """ """
        assert(type(value) == str)
        fmt =   "%ss"%(len(value))
        self._addbuf(pack(fmt,value))

    def writeByte(self,value):
        fmt = "%sb"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeUnsignedByte(self,value):
        fmt = "%sB"%self._isEndian()
        self._addbuf(pack(fmt,value))

    def writeBytes(self,bytes,offset=0,nlen=0):
        """ """
        buf = bytes.getvalue()
        strlen = nlen
        if strlen == 0:
            strlen = bytes.length();
        self._addbuf(buf[offset:strlen])

    def writeMuliteBytes(self,value):
        self._addbuf(value)

    def getbytes(self,lenght):
        """ """
        data =  self._readbuf(lenght)
        return data

    def gethavebytes(self):
        old_pos =   self.position;
        if old_pos >= self.length():
            return "";
        buf =    self.__buf[old_pos:]
        self.position   = self.length();
        return buf;
    
    def visablsize(self):
        return self.length() - self.position;
    
    def getvalue(self):
        """ """
        return self.__buf;

    def length(self):
        """ """
        nlen =  len(self.__buf)
        return nlen

    def _addbuf(self,value):
        """ """
        old_pos =   self.position
        old_buf = self.__buf[:self.position]
        new_buf = "";
        if self.position<self.length():
            new_buf = self.__buf[self.position:]
        self.__buf = old_buf + value + new_buf
        self.position = old_pos + len(value)

    def _readbuf(self,nlen):
        """ """
        old_pos =   self.position;
        new_index = self.position + nlen
        if new_index > self.length():
            raise IndexError,"遇到文件结尾"
        buf =    self.__buf[self.position:new_index]
        self.position   +=  nlen
        return buf;

    def _isEndian(self):
        """ """
        if self.endian == ByteArray.ENDIAN_BIG:
            return ">"
        else:
            return ""
    def __del__(self):
        """ """
        self.__buf=""


if __name__ == "__main__":
    bytes = ByteArray()
    #bytes.endian = CByteArray.ENDIAN_LETTLE
    bytes.writeUnsignedInt(5262679)
    bytes.writeShort(2)
    #bytes.writeUTFBytes("abcdef")
    #bytes.writeFloat(1.000)
    #bytes.compress()
    print binascii.hexlify(bytes.getvalue())
    #bytes.position  = 0
    print bytes.length()
    bytes.position = 0
    print bytes.readUnsignedInt()
    b = ByteArray()
    bytes.readBytes(b,0,2)
    print binascii.hexlify(bytes.gethavebytes());
    print  binascii.hexlify(b.getvalue())
    print b.length()
    #print bytes.readUTFBytes(6)
    #print bytes.readFloat()

